package com.taichuan.selfcheck.ui.fragment;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.TextView;
import com.orhanobut.logger.Logger;
import com.taichuan.keysupport.Key;
import com.taichuan.selfcheck.R;
import com.taichuan.selfcheck.config.PropertyDefaultValue;
import com.taichuan.selfcheck.eventbus.AlarmInputEvent;
import com.taichuan.selfcheck.eventbus.DoorCheckEvent;
import com.taichuan.selfcheck.eventbus.DoorOpenStateEvent;
import com.taichuan.selfcheck.eventbus.LeftCaseFanStateEvent;
import com.taichuan.selfcheck.eventbus.MicrowaveEvent;
import com.taichuan.selfcheck.eventbus.OutUnlockEvent;
import com.taichuan.selfcheck.eventbus.ReservedIoEvent;
import com.taichuan.selfcheck.eventbus.RightCaseFanStateEvent;
import com.taichuan.selfcheck.eventbus.TamperStateEvent;
import com.taichuan.selfcheck.mvp.presenter.EmptyPresenter;
import com.taichuan.selfcheck.mvp.viewinterface.EmptyInterface;
import com.taichuan.selfcheck.ui.dialog.ResultDialog;
import com.taichuan.selfcheck.ui.fragment.base.AppBaseFragment;
import com.taichuan.serialcommunication.SerialPortPublic;
import com.taichuan.tcutils.taichuan.SystemUtils;
import com.taichuan.tcutils.taichuan.TcDeviceType;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.concurrent.TimeUnit;
import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.BiFunction;
import io.reactivex.schedulers.Schedulers;

/**
 * 该类主要用于
 *
 * @author CamelLuo
 * @version 2019/12/5
 */
public class IOStateFragment extends AppBaseFragment<EmptyInterface, EmptyPresenter> implements EmptyInterface {

    private static final int START_LOOP_UNLOCK = 1;     //循环开锁
    private static final int STOP_LOOP_UNLOCK = 0;      //停止循环开锁

    @BindView(R.id.fragment_test_device_door_check_imageView)
    ImageView doorCheckIv;
    @BindView(R.id.fragment_test_device_tamper_switch_state_imageView)
    ImageView tamperSwitchIv;
    @BindView(R.id.fragment_test_device_unlock_button)
    Button unlockBtn;
    @BindView(R.id.fragment_test_device_loop_unlock_button)
    Button loopUnlockBtn;
    @BindView(R.id.fragment_test_device_micro_wave_state_imageView)
    ImageView microWaveIv;
    @BindView(R.id.fragment_test_device_buzzer_button)
    Button buzzerBtn;
    @BindView(R.id.fragment_test_device_case_fan_button)
    Button caseFanBtn;
    @BindView(R.id.fragment_test_device_out_unlock_state_imageView)
    ImageView outUnlockStateIv;
    @BindView(R.id.fragment_test_device_reserved_io_state_imageView)
    ImageView reservedIoStateIv;
    @BindView(R.id.ioKeySV)
    ScrollView ioKeySV;

    @BindView(R.id.fragment_test_device_door_alarm_input_imageView)
    ImageView alarmInputIoStateIv;

    @BindView(R.id.fragment_test_device_unlock_delay_tv)
    TextView unlockDelayTv;
    @BindView(R.id.fragment_test_device_unlock_delay_sb)
    SeekBar unlockDelaySb;

    @BindView(R.id.fragment_test_device_left_fan_check_imageView)
    ImageView leftFanStateIv;
    @BindView(R.id.fragment_test_device_right_fan_check_imageView)
    ImageView rightFanStateIv;
    @BindView(R.id.fan_state_layout)
    LinearLayout fanStateLayout;

    ResultDialog resultDialog;

    private final static int SCROLL_UP = 1;
    private final static int SCROLL_DOWN = 2;
    @BindView(R.id.fragment_test_device_door_check_open_close_imageView)
    ImageView doorCheckOpenCloseIv;
    private int curScrollDistance;//ScrollView当前滑动的距离
    private final String TAG = getClass().getSimpleName();

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case START_LOOP_UNLOCK:
                    //目前只有RK3399_20D_BOARD_VERTICAL_TOUCH 机型支持调节开锁时长
                    if (SystemUtils.getTcDeviceType() == TcDeviceType.RK3399_20D_BOARD_VERTICAL_TOUCH){
                        //执行可调时长开锁
                        SerialPortPublic.unlock(5);
                    }else {
                        //执行普通开锁
                        SerialPortPublic.unlock();
                    }
                    showMsg("执行自动开锁");
                    handler.sendEmptyMessageDelayed(START_LOOP_UNLOCK, 5000);
                    break;
                case STOP_LOOP_UNLOCK:
                    handler.removeMessages(START_LOOP_UNLOCK);
                    break;
            }
            return false;
        }
    });

    @Override
    protected void getBundleValues(Bundle bundle) {

    }

    @Override
    protected int setContentViewId() {
        return R.layout.fragment_io_state;
    }

    @Override
    protected void initView(View view, Bundle bundle) {
        EventBus.getDefault().register(this);

        buzzerBtn.setTag(R.id.item_click, "close");
        caseFanBtn.setTag(R.id.item_click, "close");

        if (SystemUtils.isVankeSiteBoxDevice()){
            fanStateLayout.setVisibility(View.VISIBLE);
        }else {
            fanStateLayout.setVisibility(View.GONE);
        }


        resultDialog = new ResultDialog(PropertyDefaultValue.FUNCTION_TEST_5, getResources().getString(R.string.device_test), getContext());       //设置弹窗发送的事件——门检防拆微波开锁测试

        // 检查状态需要一条一条检查，否则只有最后一条状态能正常返回
        Observable<Long> intervalOb = Observable.interval(250, TimeUnit.MILLISECONDS);
        Observable<Integer> queryIoOb = Observable.just(0x03, 0x04, 0x20);
        Observable.zip(queryIoOb, intervalOb, (BiFunction<Integer, Long, Integer>) (integer, aLong) -> integer)
                .observeOn(Schedulers.computation())
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Integer i) {
                        Log.d(TAG, "查询IO状态 onNext : thread=" + Thread.currentThread().getName() + ", i=" + i);
                        SerialPortPublic.checkIoState(i);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "查询IO状态 onComplete: thread=" + Thread.currentThread().getName());
                    }
                });

        //目前只有RK3399_20D_BOARD_VERTICAL_TOUCH 机型支持调节开锁时长
        if (SystemUtils.getTcDeviceType() == TcDeviceType.RK3399_20D_BOARD_VERTICAL_TOUCH){
            unlockDelaySb.setVisibility(View.VISIBLE);
            unlockDelayTv.setVisibility(View.VISIBLE);

            unlockDelaySb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @SuppressLint("DefaultLocale")
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    unlockDelayTv.setText(String.format("开锁延时(按键4减少，按键6增加)：%d秒", (progress + 1)));
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            });
        }else {
            unlockDelaySb.setVisibility(View.GONE);
            unlockDelayTv.setVisibility(View.GONE);
        }

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        handler.removeMessages(START_LOOP_UNLOCK);
    }

    @OnClick({
            R.id.fragment_test_device_unlock_button,
            R.id.fragment_test_device_loop_unlock_button,
            R.id.fragment_test_device_buzzer_button,
            R.id.fragment_test_device_case_fan_button
    })
    @Override
    protected void onXmlClick(View v) {
        super.onXmlClick(v);
        switch (v.getId()) {
            case R.id.fragment_test_device_unlock_button: {
                //目前只有RK3399_20D_BOARD_VERTICAL_TOUCH 机型支持调节开锁时长
                if (SystemUtils.getTcDeviceType() == TcDeviceType.RK3399_20D_BOARD_VERTICAL_TOUCH){
                    //执行可调时长开锁
                    SerialPortPublic.unlock(unlockDelaySb.getProgress() + 1);
                }else {
                    //执行普通开锁
                    SerialPortPublic.unlock();
                }
                showMsg("执行开锁");
                break;
            }
            case R.id.fragment_test_device_loop_unlock_button: {
                //循环开锁-每5秒一次
                if (loopUnlockBtn.getText().toString().equals(getResources().getString(R.string.loop_unlock))) {
                    handler.sendEmptyMessageDelayed(START_LOOP_UNLOCK, 5000);
                    loopUnlockBtn.setText(getResources().getString(R.string.loop_cancel_unlock));
                } else {
                    handler.sendEmptyMessage(STOP_LOOP_UNLOCK);
                    showMsg("已取消自动开锁");
                    loopUnlockBtn.setText(getResources().getString(R.string.loop_unlock));
                }
                break;
            }
            case R.id.fragment_test_device_buzzer_button: {
                if (buzzerBtn.getTag(R.id.item_click).equals("close")) {
                    //短音
                    SerialPortPublic.controlBuzzer(1);
                    buzzerBtn.setText(getStrById(R.string.buzzer_button_long));
                    buzzerBtn.setTag(R.id.item_click, "open");
                } else {
                    //短音
                    SerialPortPublic.controlBuzzer(0);
                    buzzerBtn.setText(getStrById(R.string.buzzer_button_short));
                    buzzerBtn.setTag(R.id.item_click, "close");
                }
                break;
            }
            case R.id.fragment_test_device_case_fan_button:{
                if (caseFanBtn.getTag(R.id.item_click).equals("close")) {
                    //开启机箱风扇
                    SerialPortPublic.controlCaseFan(true);
                    caseFanBtn.setText(getStrById(R.string.case_fan_close_button));
                    caseFanBtn.setTag(R.id.item_click, "open");
                } else {
                    //关闭机箱风扇
                    SerialPortPublic.controlCaseFan(false);
                    caseFanBtn.setText(getStrById(R.string.case_fan_open_button));
                    caseFanBtn.setTag(R.id.item_click, "close");
                }
                break;
            }
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 门检IO口 状态
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveDoorCheckState(DoorCheckEvent doorCheckEvent) {
        if (doorCheckIv != null) {
            doorCheckIv.setSelected(doorCheckEvent.isOpenDoor());
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 防拆 IO口 状态
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveTamperStateState(TamperStateEvent tamperStateEvent) {
        if (tamperSwitchIv != null) {
            tamperSwitchIv.setSelected(tamperStateEvent.isInTampering());
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 微波模块 状态
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveMicrowaveState(MicrowaveEvent microwaveEvent) {
        if (microWaveIv != null) {
            microWaveIv.setSelected(microwaveEvent.isHasPeople());
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 门开关 状态
     *
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveDoorOpenState(DoorOpenStateEvent event) {
        if (doorCheckOpenCloseIv != null) {
            doorCheckOpenCloseIv.setSelected(event.isDoorOpen());
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 外出开关 状态
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveOutUnlockState(OutUnlockEvent outUnlockEvent) {
        if (outUnlockStateIv != null) {
            outUnlockStateIv.setSelected(outUnlockEvent.isOutUnlock());
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 预留IO口 状态
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveReservedIoState(ReservedIoEvent ioEvent) {
        if (reservedIoStateIv != null) {
            reservedIoStateIv.setSelected(ioEvent.isOn());
        }
    }

    /*** 报警输入事件 */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveAlarmInputIoState(AlarmInputEvent ioEvent) {
        if (alarmInputIoStateIv != null) {
            alarmInputIoStateIv.setSelected(ioEvent.alarm);
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 左侧 机箱风扇 转动状态
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveLeftCaseFanState(LeftCaseFanStateEvent event) {
        if (leftFanStateIv != null) {
            leftFanStateIv.setSelected(event.isOpen());
        }
    }

    /**
     * 定义一个EventBus 接收方法用于接收 右侧 机箱风扇 转动状态
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveLeftCaseFanState(RightCaseFanStateEvent event) {
        if (rightFanStateIv != null) {
            rightFanStateIv.setSelected(event.isOpen());
        }
    }

    @Override
    protected EmptyPresenter createPresenter() {
        return new EmptyPresenter();
    }

    @Override
    protected boolean isAllowAutoFinishFragment() {
        return false;
    }

    @Override
    public void doOnAutoFinishFragment() {
        resultDialog.show();
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (resultDialog.isShowing()) {
            resultDialog.dispatchKeyEvent(event);
        }
        if (event.getKeyCode() == KeyEvent.KEYCODE_POUND) {
            unlockBtn.performClick();
        } else if (event.getKeyCode() == Key.Convert.KEYCODE_LONG_JING) {     //长按# 号键
            loopUnlockBtn.performClick();
        } else if (event.getKeyCode() == Key.Convert.KEYCODE_1) {     //蜂鸣器
            buzzerBtn.performClick();
        } else if (event.getKeyCode() == Key.Convert.KEYCODE_5) {     //机箱风扇
            caseFanBtn.performClick();
        } else if (event.getKeyCode() == Key.Convert.KEYCODE_2) {   //向上滑动
            scrollUIView(SCROLL_UP);
            return true;
        } else if (event.getKeyCode() == Key.Convert.KEYCODE_4) {   // 减少开锁延时
            int progress = unlockDelaySb.getProgress();
            if (progress > 0) {
                progress--;
                unlockDelaySb.setProgress(progress);
            }
            return true;
        } else if (event.getKeyCode() == Key.Convert.KEYCODE_6) {   // 增加开锁延时
            int progress = unlockDelaySb.getProgress();
            if (progress < unlockDelaySb.getMax()) {
                progress++;
                unlockDelaySb.setProgress(progress);
            }
            return true;
        } else if (event.getKeyCode() == Key.Convert.KEYCODE_8) {   //向下滑动
            scrollUIView(SCROLL_DOWN);
            return true;
        }

        return super.dispatchKeyEvent(event);
    }

    /**
     * 根据滑动类型进行页面滑动
     */
    public void scrollUIView(int scrollType) {
        //计算可滑动的最大距离
        int scrollMaxDistance = ioKeySV.getChildAt(0).getHeight() - ioKeySV.getMeasuredHeight();
        if (scrollType == SCROLL_UP) {
            if (curScrollDistance > 0) {
                curScrollDistance = curScrollDistance - ioKeySV.getMeasuredHeight() / 2;//每次滑动控件的1/2高度距离
                ioKeySV.scrollTo(0, curScrollDistance);
            } else {
                curScrollDistance = 0;
                Logger.t(TAG).e("已到顶部，无需滑动:");
            }
        } else {
            if (curScrollDistance <= scrollMaxDistance) {
                curScrollDistance = curScrollDistance + ioKeySV.getMeasuredHeight() / 2;//每次滑动控件的1/2高度距离
                ioKeySV.scrollTo(0, curScrollDistance);
                Logger.t(TAG).e("about_scroll滑动距离:" + curScrollDistance + "  滑动最大距离:" + scrollMaxDistance);
            } else {
                curScrollDistance = scrollMaxDistance;
                Logger.t(TAG).e("已到底部，无需滑动:");
            }
        }
    }
}
